// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: MIT
package server

import (
        "fmt"
        "time"
        "net/http"
        "net/http/httptest"
        "testing"
)

func TestFaviconHandler(t *testing.T) {
        favicon := NewFavicon()

        req := httptest.NewRequest("GET", "/favicon.ico", nil)
        w := httptest.NewRecorder()

        favicon.ServeHTTP(w, req)

        if w.Code != http.StatusOK {
                t.Errorf("Expected status 200, got %d", w.Code)
        }

        contentType := w.Header().Get("Content-Type")
        if contentType != "image/x-icon" {
                t.Errorf("Expected Content-Type 'image/x-icon', got '%s'", contentType)
        }

        if w.Body.Len() == 0 {
                t.Error("Favicon body should not be empty")
        }
}

func TestLandingPageHandler(t *testing.T) {
        config := LandingPageConfig{
                Name:    "Test Server",
                Version: "1.0.0",
                Links: []LandingPageLinks{
                        {Address: "/metrics", Text: "Metrics"},
                        {Address: "/health", Text: "Health"},
                },
        }

        handler, err := NewLandingPage(config)
        if err != nil {
                t.Fatalf("Failed to create landing page handler: %v", err)
        }

        // Test successful request
        req := httptest.NewRequest("GET", "/", nil)
        w := httptest.NewRecorder()

        handler.ServeHTTP(w, req)

        if w.Code != http.StatusOK {
                t.Errorf("Expected status 200, got %d", w.Code)
        }

        contentType := w.Header().Get("Content-Type")
        if contentType != "text/html; charset=UTF-8" {
                t.Errorf("Expected Content-Type 'text/html; charset=UTF-8', got '%s'", contentType)
        }

        body := w.Body.String()
        if !contains(body, "Test Server") {
                t.Error("Landing page should contain server name")
        }

        if !contains(body, "1.0.0") {
                t.Error("Landing page should contain version")
        }

        if !contains(body, "Metrics") {
                t.Error("Landing page should contain metrics link")
        }

        // Test 404 for non-root path
        req404 := httptest.NewRequest("GET", "/nonexistent", nil)
        w404 := httptest.NewRecorder()

        handler.ServeHTTP(w404, req404)

        if w404.Code != http.StatusNotFound {
                t.Errorf("Expected status 404 for non-root path, got %d", w404.Code)
        }
}

func TestLandingPageWithCustomCSS(t *testing.T) {
        customCSS := "body { background-color: red; }"
        config := LandingPageConfig{
                Name: "Test Server",
                CSS:  customCSS,
        }

        handler, err := NewLandingPage(config)
        if err != nil {
                t.Fatalf("Failed to create landing page handler: %v", err)
        }

        req := httptest.NewRequest("GET", "/", nil)
        w := httptest.NewRecorder()

        handler.ServeHTTP(w, req)

        body := w.Body.String()
        if !contains(body, customCSS) {
                t.Error("Landing page should contain custom CSS")
        }
}

func TestLandingPageWithEmptyConfig(t *testing.T) {
        config := LandingPageConfig{
                Name: "Test Server",
        }

        handler, err := NewLandingPage(config)
        if err != nil {
                t.Fatalf("Failed to create landing page handler: %v", err)
        }

        req := httptest.NewRequest("GET", "/", nil)
        w := httptest.NewRecorder()

        handler.ServeHTTP(w, req)

        if w.Code != http.StatusOK {
                t.Errorf("Expected status 200, got %d", w.Code)
        }

        // Should use default CSS when none provided
        body := w.Body.String()
        if !contains(body, "background: linear-gradient") {
                t.Error("Landing page should contain default CSS")
        }
}

// Helper function to check if a string contains a substring
func contains(s, substr string) bool {
        return len(s) >= len(substr) && (s == substr || len(s) > len(substr) && (s[:len(substr)] == substr || s[len(s)-len(substr):] == substr || containsSubstring(s, substr)))
}

func containsSubstring(s, substr string) bool {
        for i := 0; i <= len(s)-len(substr); i++ {
                if s[i:i+len(substr)] == substr {
                        return true
                }
        }
        return false
}

func BenchmarkLandingPageWithManyLinks(b *testing.B) {
        links := make([]LandingPageLinks, 50)
        for i := 0; i < 50; i++ {
                links[i] = LandingPageLinks{
                        Address: fmt.Sprintf("/endpoint%d", i),
                        Text:    fmt.Sprintf("Endpoint %d", i),
                }
        }

        config := LandingPageConfig{
                Name:    "Benchmark Server with Many Links",
                Version: "1.0.0",
                Links:   links,
        }

        handler, err := NewLandingPage(config)
        if err != nil {
                b.Fatalf("Failed to create landing page handler: %v", err)
        }

        b.ResetTimer()
        for i := 0; i < b.N; i++ {
                req := httptest.NewRequest("GET", "/", nil)
                w := httptest.NewRecorder()
                handler.ServeHTTP(w, req)
        }
}

func TestLandingPageContentLength(t *testing.T) {
        config := LandingPageConfig{
                Name:    "Content Length Test Server",
                Version: "1.0.0",
                Links: []LandingPageLinks{
                        {Address: "/metrics", Text: "Metrics"},
                },
        }

        handler, err := NewLandingPage(config)
        if err != nil {
                t.Fatalf("Failed to create landing page handler: %v", err)
        }

        req := httptest.NewRequest("GET", "/", nil)
        w := httptest.NewRecorder()

        handler.ServeHTTP(w, req)

        if w.Body.Len() == 0 {
                t.Error("Landing page body should not be empty")
        }

        // Should contain HTML structure
        body := w.Body.String()
        if !contains(body, "<!DOCTYPE html>") {
                t.Error("Landing page should contain HTML doctype")
        }

        if !contains(body, "<html>") {
                t.Error("Landing page should contain HTML tag")
        }

        if !contains(body, "</html>") {
                t.Error("Landing page should contain closing HTML tag")
        }
}

func TestLandingPagePerformance(t *testing.T) {
        config := LandingPageConfig{
                Name:    "Performance Test Server",
                Version: "2.0.0",
                Links: []LandingPageLinks{
                        {Address: "/metrics", Text: "Metrics"},
                        {Address: "/health", Text: "Health"},
                        {Address: "/debug", Text: "Debug"},
                },
        }

        handler, err := NewLandingPage(config)
        if err != nil {
                t.Fatalf("Failed to create landing page handler: %v", err)
        }

        start := time.Now()

        req := httptest.NewRequest("GET", "/", nil)
        w := httptest.NewRecorder()

        handler.ServeHTTP(w, req)

        duration := time.Since(start)

        if w.Code != http.StatusOK {
                t.Errorf("Expected status 200, got %d", w.Code)
        }

        if duration > 100*time.Millisecond {
                t.Errorf("Response time too slow: %v", duration)
        }

        t.Logf("Response time: %v", duration)
}

func BenchmarkFaviconHandler(b *testing.B) {
        favicon := NewFavicon()

        for i := 0; i < b.N; i++ {
                req := httptest.NewRequest("GET", "/favicon.ico", nil)
                w := httptest.NewRecorder()
                favicon.ServeHTTP(w, req)
        }
}

func BenchmarkLandingPageHandler(b *testing.B) {
        config := LandingPageConfig{
                Name:    "Benchmark Server",
                Version: "1.0.0",
                Links: []LandingPageLinks{
                        {Address: "/metrics", Text: "Metrics"},
                        {Address: "/health", Text: "Health"},
                },
        }

        handler, err := NewLandingPage(config)
        if err != nil {
                b.Fatalf("Failed to create landing page handler: %v", err)
        }

        b.ResetTimer()
        for i := 0; i < b.N; i++ {
                req := httptest.NewRequest("GET", "/", nil)
                w := httptest.NewRecorder()
                handler.ServeHTTP(w, req)
        }
}

